package com.hk.threadpool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author: dpb
 * @Description TODO
 * @date: 2023/2/5 23:15
 * @Version 1.0
 */
@RestController
@RequestMapping("threadPoolOOM")
@Slf4j
public class ThreadPoolOOMController {

    private void printStats(java.util.concurrent.ThreadPoolExecutor threadPool) {
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            log.info("=========================");
            log.info("Pool Size: {}", threadPool.getPoolSize());
            log.info("Active Threads: {}", threadPool.getActiveCount());
            log.info("Number of Tasks Completed: {}", threadPool.getCompletedTaskCount());
            log.info("Number of Tasks in Queue: {}", threadPool.getQueue().size());

            log.info("=========================");
        }, 0, 1, TimeUnit.SECONDS);
    }

    @GetMapping("oom1")
    public void oom1() throws InterruptedException {

        ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
        printStats(threadPoolExecutor);
        for (int i = 0; i < 100000000; i++) {
            threadPoolExecutor.execute(() -> {
                String payload = IntStream.rangeClosed(1,1000000)
                        .mapToObj(__ -> "a")
                        .collect(Collectors.joining("")) + UUID.randomUUID().toString();
                try {
                    TimeUnit.SECONDS.sleep(50);
                } catch (InterruptedException e) {
                }
                log.info(payload);
            });
        }
        threadPoolExecutor.shutdown();
        threadPoolExecutor.awaitTermination(50,TimeUnit.SECONDS);

    }



}
